# -*- coding: utf-8 -*-
"""
Created on Thu Oct 26 16:04:57 2017

@author: xuanlei
"""

import encoder_lstm as lstm
import get_data as dl
import win_data as mvd
import pandas as pd
import tensorflow as tf
from sklearn.cross_validation import train_test_split
import numpy as np
from sklearn.metrics import classification_report
from sklearn.preprocessing import normalize, MaxAbsScaler
import random
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
#==============================================================================
# Global Option
#==============================================================================
feature_list = [0,       1,       2,       3,       4,       5,       6,       7,
             8,       9,      10,      11,      12,      13,      14,      15,
            16,      17,      18,      19,      20,      21,      22,      23,
            24,      25,      26,      27,      28,      29,      30,      31,
            32,      33,      34,      35,      36,      37,      38,      39,
            40,      41]

label_list = 'label'


#==============================================================================
# Hyper-Para Setting
#==============================================================================

input_size = len(feature_list)
cell_size = 21
num_size = 3
LR = 0.001
n_steps = 10
h1_size = 19
h2_size = 25
h3_size = 18
output_size = 1
batch_size = 100

def dataframe_to_tensor(batch_data, feature_list, nm=True):
    if nm == True:
        feature_list_tran = [np.array(item.loc[:,feature_list], dtype='float32') for item in batch_data]
#        feature_list_tran = [np.array(item.loc[:,feature_list], dtype='float32') for item in batch_data]
        xs = np.array(feature_list_tran, dtype='float32')
#        print(xs.shape)
    else:
        feature_list_tran = [np.array(item.loc[:,feature_list], dtype='float32') for item in batch_data]
        xs = np.array(feature_list_tran, dtype='float32')
#    print(xs.shape)
    return xs
    

def confusion_matrix_plot_matplotlib(y_truth, y_predict,cmap=plt.cm.Blues):
    """Matplotlib绘制混淆矩阵图
    parameters   cmap=plt.cm.Blues
    ----------
        y_truth: 真实的y的值, 1d array
        y_predict: 预测的y的值, 1d array
        cmap: 画混淆矩阵图的配色风格, 使用cm.Blues
    """
    cm = confusion_matrix(y_truth, y_predict)
    plt.matshow(cm, cmap=cmap)  # 混淆矩阵图
    plt.colorbar()  # 颜色标签
 
    for x in range(len(cm)):  # 数据标签
        for y in range(len(cm)):
            plt.annotate(cm[x, y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
 
    plt.ylabel('True label')  # 坐标轴标签
    plt.xlabel('Predicted label')  # 坐标轴标签
    plt.show()  # 显示作图结果

def train():

    see_pp = []
    see_test_pp = []
    
    tf.reset_default_graph()
    print('---------> 开始读取数据！')
#    win_data_run,win_data_err = dl.start()
    print('---------> 数据读取完毕，开始生成滑窗数据！')
 #   run,err,rtest,result_all =  mvd.start(win_data_run,win_data_err)
    model = lstm.LSTMRNN(n_steps, input_size, output_size, cell_size, h1_size, h2_size, h3_size, LR,num_size, batch_size)
    print('----------> LSTM模型架构完毕，开始训练运行模型！')
    saver = tf.train.Saver()
    with tf.Session() as sess:
        init_op = tf.global_variables_initializer()
        sess.run(init_op)
        merged = tf.summary.merge_all()
        writer = tf.summary.FileWriter("E:/logs_en_lstmx/", sess.graph)
        
        with tf.variable_scope('scope', reuse=True):
            max_epoch = 1
            epoch = 0
            train_sample, test_sample = train_test_split(ls_train2, train_size=139118, test_size=24551)
            print('---------> 训练集与测试集划分完毕，开始训练模型！')
            while epoch < max_epoch:
               
                batch_start = 0
                for i in range(1,1391):
                    train_feature_list = [item for item in train_sample[batch_start:batch_start+100]]
                    xs_input = dataframe_to_tensor(train_feature_list, feature_list)
                    ys_input = dataframe_to_tensor(train_feature_list, label_list, nm=False)
                    feed_dict_train = {model.xs:xs_input, model.ys:ys_input.reshape([-1,1]),
                                       model.keep_prob: np.array(0.7,  dtype='float32'), model.train_phase: True}
                    batch_start += 100
                    _, cost, model.state = sess.run(
                            [model.train_op, model.cost, model.cells_final_state], feed_dict=feed_dict_train)
                    if i%2 == 0:
                        rs = sess.run(merged,feed_dict=feed_dict_train)
                        writer.add_summary(rs, i)
#                        print(i)
#                        print('-------> now_cost: {0}'.format(cost, 2))
                        
                    if i%500 == 0:
                        batch_start_test = 0
                        see_y = []
                        see_p = []
                        for t in range(245):
                            test_feature_list = [item for item in test_sample[batch_start_test:batch_start_test+100]]
                            xs_test_input = dataframe_to_tensor(test_feature_list, feature_list)
                            vail_predict = sess.run(model.pred, feed_dict={model.xs:xs_test_input,
                                                                           model.keep_prob:np.array(1, dtype='float32'),
                                                                           model.train_phase: False})
                            ys_test = dataframe_to_tensor(test_feature_list, label_list, nm=False).reshape([-1,1])
                            result = []
                            for item in vail_predict:
                                if item >= 0.3:
                                    result.append(1)
                                else:
                                    result.append(0)
                            see_y.extend(int(x) for x in ys_test)
                            see_p.extend(result)
                            see_pp.extend(vail_predict)
                            batch_start_test += 100
                        print("------->中间结果: epoch: {0}".format(epoch+1))
                        print('-------> now_cost: {0}'.format(cost, 2))
#                        print(see_y,'!!!!!!!!!!!!!!!!!!!!!', see_p)
                        print(classification_report(see_y, see_p))
#单独测试t0后数据  
                see_y_test = []
                see_p_test = []        
                j = 0
                for x in range(197):
                    test_feature_l = ls_re_test2[j:j+100]
                    xs_test_input2 = dataframe_to_tensor(test_feature_l, feature_list)
                    vail_predict = sess.run(model.pred, feed_dict={model.xs:xs_test_input2,
                                                                   model.keep_prob:np.array(1, dtype='float32'),
                                                                   model.train_phase: False})
                    ys_test2 = dataframe_to_tensor(test_feature_l, label_list, nm=False).reshape([-1,1])
                    result_test = []
                    for item in vail_predict:
                        if item > 0.3:
                            result_test.append(1)
                        else:
                            result_test.append(0)
                    see_test_pp.extend(vail_predict)
                    see_y_test.extend(int(x) for x in ys_test2)
                    see_p_test.extend(result_test)
    #                see_pp.append(vail_predict)

                    j+=100
                print('>>>>>>>>>>>>>>>>>>>> real all test <<<<<<<<<<<<<<<<<<<<<<<<<<<<')
                print(classification_report(see_y_test, see_p_test))
                confusion_matrix_plot_matplotlib(see_p_test,see_y_test,cmap=plt.cm.tab10_r)
                saver.save(sess, 'lstm_para_cx/para_log')
                epoch += 1                
                
        return see_y,see_p,see_y_test,see_p_test,see_pp,see_test_pp,test_sample,train_sample
        



        
    
    


if __name__ == '__main__':
    see_y,see_p,see_y_test,see_p_test,see_pp,see_test_pp,test_sample,train_sample = train()